﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BadHabit.Factory.Controls {
    /// <summary>
    /// Interaction logic for ProjectTabControl.xaml
    /// </summary>
    public partial class ProjectTabControl : UserControl {


        
      
        /// <summary>
        /// Default constructor.
        /// </summary>
        public ProjectTabControl() {
            Initialized += new EventHandler(ProjectTabControl_Initialized);
            InitializeComponent();            
            
        }

        void ProjectTabControl_Initialized(object sender, EventArgs e) {
            if (global::BadHabit.Factory.Windows.Properties.Settings.Default.TaskViewMode.Equals(BadHabit.Factory.Client.TaskViewModes.LISTVIEW.ToString()))
                ChangeTaskTabItem();
        }

        /// <summary>
        /// Every time the tab changes, move the arrow.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) {

            // why i wrote the line?
            // 'cuz WPF has a bug that fires SelectionChange when any child control
            // of a tabControl has a selector(listbox, datagrid, etc...).
            // so i make sure here that is the tabcontrol that is firing it
            if (e.OriginalSource != tabControl)
                return;


            // quite a ugly code, but is the only way to cancel a SelectionChanged event
            /*
            if (Client.FactoryMainWindow != null && Client.FactoryMainWindow.ProjectHasChanges) {

                MessageBoxResult d = 
                    Windows.Error.ShowDialog(Properties.Resources.Commit_project_changes_,
                    Properties.Resources.Commit_Changes, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);

                if (d == MessageBoxResult.Yes) 
                    Client.FactoryMainWindow.Save();
                else
                    Client.FactoryMainWindow.Undo();
            }*/
            
            AnimateSelectorArrow();
        }

        /// <summary>
        /// Gets the position of the selected item.
        /// </summary>
        private Point SelectedItemPosition {
            get {
                TabItem selectedItem = (TabItem)tabControl.SelectedItem;        
                // THIS 20 value is the TABITEM MARGIN
                return selectedItem.TranslatePoint(new Point((selectedItem.ActualWidth + 20)/2, selectedItem.ActualHeight / 2), (UIElement)tabControl);
            }
        }

        /// <summary>
        /// Gets the position of the selector arrow.
        /// </summary>
        private Point SelectorArrowPosition {
            get {
                if (selectorArrow == null)
                    return new Point(0, 0);
                return selectorArrow.TranslatePoint(new Point(selectorArrow.ActualWidth/2, selectorArrow.ActualHeight/2), (UIElement)tabControl);
            }
        }

        /// <summary>
        /// Moves the selector arrow to the selected item.
        /// </summary>
        private void AnimateSelectorArrow() {

            if (selectorMark == null)
                return;

            double des = SelectedItemPosition.X - SelectorArrowPosition.X;

            DoubleAnimation anime = new DoubleAnimation();            
            anime.By = des + (selectorArrow.ActualWidth);
            anime.By = des;
            anime.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 800));
            anime.DecelerationRatio = 1;
            

            Storyboard sb = new Storyboard();
            sb.Children.Add(anime);

            Storyboard.SetTargetName(anime, selectorMark.Name);
            Storyboard.SetTargetProperty(anime, new PropertyPath(StackPanel.WidthProperty));

            anime.Freeze();

            sb.Begin(this);
        }


        /// <summary>
        /// When loaded, sets the arrow position and sets the tab items visibility.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UserControl_Loaded(object sender, RoutedEventArgs e) {
            AnimateSelectorArrow();            
        }

        /// <summary>
        /// Every time the context change, request new data for the selected panel.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) {
            
            if (DataContext == null) {
                tabControl.IsEnabled = false;
                return;
            }            
            tabControl.IsEnabled = true;

            
        }


        /// <summary>
        /// Changes the task panel for post it panel and vise-versa.
        /// </summary>
        public void ChangeTaskTabItem() {
            if (TaskTabPanel is TaskPanel) {
                TaskTabPanel = new TaskPostItPanel();
                global::BadHabit.Factory.Windows.Properties.Settings.Default.TaskViewMode = BadHabit.Factory.Client.TaskViewModes.POSTIT.ToString();
            } else {
                TaskTabPanel = new BadHabit.Factory.Controls.TaskPanel();
                global::BadHabit.Factory.Windows.Properties.Settings.Default.TaskViewMode = BadHabit.Factory.Client.TaskViewModes.LISTVIEW.ToString();
            }
        }

        public BadHabit.Factory.Controls.TaskPanelBase TaskTabPanel {
            get {
                return taskTabItem.Content as BadHabit.Factory.Controls.TaskPanelBase;
            }
            private set {
                taskTabItem.Content = value;
            }
        }


        /// <summary>
        /// Gets the panel DataContext as a ProjectDataSet.
        /// </summary>
        public Data.ProjectDataSet DataContextAsProjectDataSet {
            get {
                return DataContext as Data.ProjectDataSet;
            }
        }

        /// <summary>
        /// Gets the panel DataContext as a ProjectDataSet.
        /// </summary>
        public Data.ProjectDataSet.ProjectRow Project {
            get {
                if (DataContextAsProjectDataSet != null && DataContextAsProjectDataSet.Project.Count > 0) {
                    return DataContextAsProjectDataSet.Project[0];
                }
                return null;
            }
        }

        public bool IsChangingContext { get; private set; }


        public void ChangeDataContext(Data.ProjectDataSet dsProject) {

            IsChangingContext = true;

            DataContext = dsProject;

            IsChangingContext = false;

            foreach (TabItem tabItem in tabControl.Items) {
                GenericPanel panel = tabItem.Content as GenericPanel;
                if (panel.IsSelected)
                    panel.CallRequestData();
            }

            // sets the taskpanel to ISENABLE, cuz it might had been setted to FALSE when backlog was dirty
            Controls.TaskPanelBase taskPanel = taskTabItem.Content as Controls.TaskPanelBase;
            if (taskPanel != null) {
                taskPanel.IsEnabled = true;            
            }


        }


        public Data.TaskDataSet.TaskDataTable TaskDataContext {
            get {
                TaskPanelBase taskPanel = taskTabItem.Content as TaskPanelBase;
                if (taskPanel == null)
                    return null;
                return taskPanel.TaskDataContext;
                
            }
        }

        private void tabControl_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e) {
            AnimateSelectorArrow();
        }

        
        


     
    }
}
